package com.qianbei.common.utilis;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 身份证相关操作
*/
public class IDCard 
{
	
	/**
	* 构造方法
	*/
	public IDCard()
	{}

	/**
	* 功能：把15位身份证转换成18位
	* @param  id
	* @return newid or id
	*/
	public static final String getIDCard_18bit(String id)
	{
	  //若是15位，则转换成18位；否则直接返回ID
	  if(15 == id.length())
	  {
		  final int [] W = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1};
		  final String [] A ={"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
		  int i,j,s=0;
		  String newid;
		  newid = id;
		  newid = newid.substring(0,6)+"19"+newid.substring(6,id.length());
		  for ( i=0;i<newid.length() ;i++ )
		  {
			  j= Integer.parseInt(newid.substring(i,i+1))*W[i];
			  s=s+j;
		  }
		  s = s%11;
		  newid = newid+A[s];
		  return newid;
	  }
	  else
	  {
		  return id;
	  } 
	}
	/**
	* 从身份证获取出生日期
	* @param cardNumber 已经校验合法的身份证号
	* @return Strig YYYY-MM-DD 出生日期
	*/
	public static String getBirthDateFromCard(String cardNumber)
	{
		String card = cardNumber.trim();
	    String year;
	    String month;
	    String day;
	    if (card.length() == 18)
	    { //处理18位身份证
	        year=card.substring(6,10);
	        month=card.substring(10,12);
	        day=card.substring(12,14);
	    }
	    else
	    { //处理非18位身份证
	    	year=card.substring(6,8);
	        month=card.substring(8,10);
	        day=card.substring(10,12);
	        year="19"+year;        
	    }
	    if (month.length()==1)
	    {
	        month="0"+month; //补足两位
	    }
	    if (day.length()==1)
	    {
	        day="0"+day; //补足两位
	    }
	    return year+"-"+month+"-"+day;
	}
	
	/**
	* 从身份证获取出生日期
	* @param cardNumber 已经校验合法的身份证号
	* @return Strig YYYY-MM-DD 出生日期
	*/
	public static java.sql.Date getBirthFromCard(String cardNumber)
	{
		String birthString = getBirthDateFromCard(cardNumber);
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		java.sql.Date birthDate= new java.sql.Date(new Date().getTime());
		//将字符串转换为Date
		try 
		{
			Date date = df.parse(birthString);
			birthDate=new java.sql.Date(date.getTime());
		} 
		catch (ParseException e) 
		{
			// TODO 自动生成 catch 块
			e.printStackTrace();
		}
		return  birthDate;
	}
	/**
	* 根据身份证计算周岁
	*/
	public static   int   getAge(String   IDCardNum)
	{  
        Calendar   cal1   =   Calendar.getInstance();  
        Calendar   today   =   Calendar.getInstance();
        //如果身份证15位则将其转化为18位
        if(IDCardNum.length()==15)
        IDCardNum=getIDCard_18bit(IDCardNum);
        cal1.set(Integer.parseInt(IDCardNum.substring(6,10)),  
        Integer.parseInt(IDCardNum.substring(10,12)),  
        Integer.parseInt(IDCardNum.substring(12,14)));  
        return   getYearDiff(today, cal1);  
    }  
 
   public static int getYearDiff(Calendar cal,Calendar cal1)
   {
	   int m = (cal.get(cal.MONTH)) - (cal1.get(cal1.MONTH));  
       int y = (cal.get(cal.YEAR)) - (cal1.get(cal1.YEAR));  
       return (y * 12 + m)/12;  
   }  
   /**
    * 验证手机号码
    * */
   public static boolean isMobileNO(String mobiles)
   {     
//       Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,2,3,5-9]))\\d{8}$");  
       Pattern p = Pattern.compile("^[1][3-8]\\d{9}$");  
       Matcher m = p.matcher(mobiles);     
       return m.matches();     
   } 
   /**
    * 验证邮箱
    * */
   public static boolean isEmail(String email)
   {
       String str="^([a-zA-Z0-9.]*[-_]?[a-zA-Z0-9]+)*@([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)+[\\.][A-Za-z]{2,3}([\\.][A-Za-z]{2})?$";
       Pattern p = Pattern.compile(str);
       Matcher m = p.matcher(email);     
       return m.matches();     
   }

   /**  
    * 功能：身份证的有效验证  
    * @param IDStr 身份证号  
    * @return 有效：返回"" 无效：返回String信息  
    * @throws ParseException  
    */  
   public static String iDCardValidate(String IDStr) throws ParseException 
   {   
       String errorInfo = "";// 记录错误信息   
       String[] ValCodeArr = { "1", "0", "x", "9", "8", "7", "6", "5", "4","3", "2" };   
       String[] Wi = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7","9", "10", "5", "8", "4", "2" };   
       String Ai = "";   
       // ================ 号码的长度 15位或18位 ================   
       if (IDStr.length() != 15 && IDStr.length() != 18) 
       {   
           errorInfo = "身份证号码长度应该为15位或18位";   
           return errorInfo;   
       }   
       // =======================(end)========================   
 
       // ================ 数字 除最后以为都为数字 ================   
       if (IDStr.length() == 18) 
       {   
           Ai = IDStr.substring(0, 17);   
       } 
       else if (IDStr.length() == 15) 
       {   
           Ai = IDStr.substring(0, 6) + "19" + IDStr.substring(6, 15);   
       }   
       if (isNumeric(Ai) == false) 
       {   
           errorInfo = "身份证15位号码都应为数字;18位号码除最后一位外，都应为数字";   
           return errorInfo;   
       }   
       // =======================(end)========================   
 
       // ================ 出生年月是否有效 ================   
       String strYear = Ai.substring(6, 10);// 年份   
       String strMonth = Ai.substring(10, 12);// 月份   
       String strDay = Ai.substring(12, 14);// 月份   
       if (isDataFormat(strYear + "-" + strMonth + "-" + strDay) == false) 
       {   
           errorInfo = "身份证生日无效";   
           return errorInfo;   
       }   
       GregorianCalendar gc = new GregorianCalendar();   
       SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");   
       if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150  
               || (gc.getTime().getTime() - s.parse(strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) 
       {   
           errorInfo = "身份证生日不在有效范围";   
           return errorInfo;   
       }   
       if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) 
       {   
           errorInfo = "身份证月份无效";   
           return errorInfo;   
       }   
       if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) 
       {   
           errorInfo = "身份证日期无效";   
           return errorInfo;   
       }   
       // =====================(end)=====================   
 
       // ================ 地区码时候有效 ================   
       Hashtable h = GetAreaCode();   
       if (h.get(Ai.substring(0, 2)) == null) 
       {   
           errorInfo = "身份证地区编码错误";   
           return errorInfo;   
       }   
       // ==============================================   
 
       // ================ 判断最后一位的值 ================   
       int TotalmulAiWi = 0;   
       for (int i = 0; i < 17; i++) 
       {   
           TotalmulAiWi = TotalmulAiWi   
                   + Integer.parseInt(String.valueOf(Ai.charAt(i)))   
                   * Integer.parseInt(Wi[i]);   
       }   
       int modValue = TotalmulAiWi % 11;   
       String strVerifyCode = ValCodeArr[modValue];   
       Ai = Ai + strVerifyCode;   
 
       if (IDStr.length() == 18) 
       {
    	   if (Ai.equals(IDStr) == false) 
           {
    		   errorInfo = "身份证无效，不是合法的身份证号码";   
               return errorInfo;   
           }   
       } 
       else 
       {
    	   return "";   
       }   
        // =====================(end)=====================   
       return "";   
    }
   
   /**  
     * 功能：判断字符串是否为数字  
     * @param str  
     * @return  
     */  
    private static boolean isNumeric(String str) 
    {   
        Pattern pattern = Pattern.compile("[0-9]*");   
        Matcher isNum = pattern.matcher(str);   
        if (isNum.matches()) 
        {   
            return true;   
        } 
        else 
        {   
            return false;   
        }   
    }
    /**  
     * 功能：设置地区编码  
     * @return Hashtable 对象  
     */  
    private static Hashtable GetAreaCode() 
    {   
        Hashtable hashtable = new Hashtable();   
        hashtable.put("11", "北京");   
        hashtable.put("12", "天津");   
        hashtable.put("13", "河北");   
        hashtable.put("14", "山西");   
        hashtable.put("15", "内蒙古");   
        hashtable.put("21", "辽宁");   
        hashtable.put("22", "吉林");   
        hashtable.put("23", "黑龙江");   
        hashtable.put("31", "上海");   
        hashtable.put("32", "江苏");   
        hashtable.put("33", "浙江");   
        hashtable.put("34", "安徽");   
        hashtable.put("35", "福建");   
        hashtable.put("36", "江西");   
        hashtable.put("37", "山东");   
        hashtable.put("41", "河南");   
        hashtable.put("42", "湖北");   
        hashtable.put("43", "湖南");   
        hashtable.put("44", "广东");   
        hashtable.put("45", "广西");   
        hashtable.put("46", "海南");   
        hashtable.put("50", "重庆");   
        hashtable.put("51", "四川");   
        hashtable.put("52", "贵州");   
        hashtable.put("53", "云南");   
        hashtable.put("54", "西藏");   
        hashtable.put("61", "陕西");   
        hashtable.put("62", "甘肃");   
        hashtable.put("63", "青海");   
        hashtable.put("64", "宁夏");   
        hashtable.put("65", "新疆");   
        hashtable.put("71", "台湾");   
        hashtable.put("81", "香港");   
        hashtable.put("82", "澳门");   
        hashtable.put("91", "国外");   
        return hashtable;   
    }  

	/**验证日期字符串是否是YYYY-MM-DD格式
	 * @param str
	 * @return
	 */
	public static boolean isDataFormat(String str)
	{
		boolean flag=false;
		//String regxStr="[1-9][0-9]{3}-[0-1][0-2]-((0[1-9])|([12][0-9])|(3[01]))";
		String regxStr="^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$";
		Pattern pattern1=Pattern.compile(regxStr);
		Matcher isNo=pattern1.matcher(str);
		if(isNo.matches())
		{
			flag=true;
		}
		return flag;
	}
//身份证号码验证：end


    /**
     * 检查 身份证合法
     */
    public static boolean isCard(String s_aStr) {
        // 定义判别用户身份证号的正则表达式（要么是15位，要么是18位，最后一位可以为字母）
        Pattern idNumPattern = Pattern
                .compile("(\\d{14}[0-9a-zA-Z])|(\\d{17}[0-9a-zA-Z])");
        // 通过Pattern获得Matcher
        Matcher idNumMatcher = idNumPattern.matcher(s_aStr);
        // 判断用户输入是否为身份证号
        if (idNumMatcher.matches()) {
            return true;
        } else {
            return false;
            // 如果不是，输出信息提示用户
        }

    }
} 